import wx
import wx.adv
import time
import datetime
import os
import sys
# import pyautogui
import win32api
import configparser
import random

config_path = './config.ini'
if not os.path.isfile(config_path):
    open(config_path, 'w')
global_config = configparser.ConfigParser()
global_config.read(config_path)
global_btime = ''
if global_config.has_section('base'):
    if global_config.has_option('base', 'time'):
        global_btime = global_config.get('base', 'time')
else:
    global_config.add_section('base')
if global_btime == '':
    global_btime = '18:30'
    global_config.set('base', 'time', global_btime)
    global_config.write(open(config_path, 'w'))

# print(global_btime)

no_resize = wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP

APP_NAME = '下班倒计时'
APP_VERSION = 'V3.1415926535898'

ID_ABOUT = 1004
ID_CLOSESHOW = 1005
ID_MENU_EXIT = 1006
ID_MENU_ABOUT = 1007
ID_MENU_SETTING = 1008


def ResourcePath(relativePath):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    basePath = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(basePath, relativePath)

# p = (x, y)
# r = (x, y, w, h)
def pointInRect(p, r):
    return p[0] >= r[0] and p[0] <= (r[0] + r[2]) and p[1] >= r[1] and p[1] <= (r[1] + r[3])


class TaskBarIcon(wx.adv.TaskBarIcon):
    def __init__(self, frame):
        wx.adv.TaskBarIcon.__init__(self)
        self.frame = frame
        self.SetIcon(wx.Icon(ResourcePath('xbdjs.ico'), wx.BITMAP_TYPE_ICO), '')
        self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.Screenshot)
        self.Bind(wx.adv.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarLeftDClick)
        self.Bind(wx.adv.EVT_TASKBAR_MOVE, self.OnTaskBarMove)
        self.Bind(wx.EVT_MENU, self.frame.OnAbout, id=ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnCloseshow, id=ID_CLOSESHOW)

        self.tipFrame = None
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        self.on_move = 0
        self.px = 0
        self.py = 0
        self.ofx = 0
        self.ofy = 0
        self.task_bar_rect = [0, 0, 0, 0]


    def Screenshot(self, event):
        if not self.tipFrame:
            return
        self.tipFrame.Screenshot(event)

    def OnTaskBarLeftDClick(self, event):
        if self.frame.IsIconized():
            self.frame.Iconize(False)
        if not self.frame.IsShown():
            self.frame.Show(True)
        self.frame.Raise()

    def OnTaskBarMove(self, event):
        if self.on_move > 0:
            self.px, self.py = win32api.GetCursorPos()
            self.SetTaskBarRect(self.px, self.py)
            if not self.tipFrame:

                monitorInfo = win32api.GetMonitorInfo(win32api.MonitorFromPoint((0, 0)))
                # print('monitor info:{}'.format(monitorInfo))
                monitor = monitorInfo.get('Monitor')
                # print('屏幕分辨率:{}'.format(monitor))
                work = monitorInfo.get('Work')
                # print('工作区间:{}'.format(work))
                if work[0] == 0 and work[1] == 0:
                    if work[2] == monitor[2]:
                        self.ofx = -45
                        self.ofy = -83
                    else:
                        self.ofx = -93
                        self.ofy = -40
                else:
                    if work[0] == monitor[0]:
                        self.ofx = -95
                        self.ofy = 5
                    else:
                        self.ofx = 5
                        self.ofy = -85
                self.tipFrame = TipFrame(pos=(self.px + self.ofx, self.py + self.ofy), pframe=self.frame)
                self.tipFrame.Show(True)
                self.timer.Start(1000)
            else:
                self.tipFrame.SetPosition((self.px + self.ofx, self.py + self.ofy))

        self.on_move += 1

    def SetTaskBarRect(self, x, y):
        # print(self.task_bar_rect[2] + self.task_bar_rect[3])
        if self.task_bar_rect[2] + self.task_bar_rect[3] > 200:
            self.task_bar_rect[0] = 0
        if self.task_bar_rect[0] == 0:
            self.task_bar_rect = [x, y, 10, 10]
        else:
            if self.task_bar_rect[0] > x:
                self.task_bar_rect[2] += self.task_bar_rect[0] - x
                self.task_bar_rect[0] = x
            elif self.task_bar_rect[0] + self.task_bar_rect[2] < x:
                self.task_bar_rect[2] += x - self.task_bar_rect[0] - self.task_bar_rect[2]

            if self.task_bar_rect[1] > y:
                self.task_bar_rect[3] += self.task_bar_rect[1] - y
                self.task_bar_rect[1] = y
            elif self.task_bar_rect[1] + self.task_bar_rect[3] < y:
                self.task_bar_rect[3] += y - self.task_bar_rect[1] - self.task_bar_rect[3]
        # print(self.task_bar_rect)

    def StopTimer(self):
        # print('StopTimer')
        self.tipFrame.Destroy()
        # print(self.tipFrame)
        self.tipFrame = None
        self.timer.Stop()

    def OnTimer(self, event):
        x, y = win32api.GetCursorPos()
        if not pointInRect((x, y), self.task_bar_rect):
            self.StopTimer()

    def OnCloseshow(self, event):
        self.frame.Close(True)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        menu.Append(ID_ABOUT, '关于')
        menu.Append(ID_CLOSESHOW, '退出')
        return menu

class TipFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, pos=wx.DefaultPosition, title='', pframe=None):

        wx.Frame.__init__(self, parent, id, title, pos, size=(100, 80), style=no_resize)

        self.pframe = pframe

        self.SetBackgroundColour(wx.Colour('WHITE'))
        # self.panel = wx.Panel(self)

        self.st2 = wx.StaticText(self, -1, "", pos=(5, 5))
        self.st3 = wx.StaticText(self, -1, "", pos=(5, 5 + 25))
        self.st4 = wx.StaticText(self, -1, "", pos=(5, 5 + 50))

        # self.dc = wx.ClientDC(self)

        # brush = wx.Brush("white")
        # self.dc.SetBackground(brush)

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        self.SetTimeData()
        # self.OnPaint()
        self.timer.Start(1000)

    def StopTimer(self):
        self.st2.SetLabel("")
        self.st3.SetLabel("")
        self.st4.SetLabel("")
        self.timer.Stop()
        time.sleep(0.1)

    def OnTimer(self, event):
        self.SetTimeData()
        # self.OnPaint()

    def SetTimeData(self):
        timeret = self.pframe.timeOffset()
        if timeret['errcode'] == 10000:
            self.StopTimer()
            # self.st2.SetLabel(timeret['errmsg'])
            self.st2.SetLabel(timeret['data'][0])
            self.st3.SetLabel(timeret['data'][1])
            self.st4.SetLabel(timeret['data'][2])
            return
        elif timeret['errcode'] > 0:
            self.StopTimer()
            self.st1.SetLabel(timeret['errmsg'])
            return

        self.st2.SetLabel(timeret['data']['s'])
        self.st3.SetLabel(timeret['data']['ms'])
        self.st4.SetLabel(timeret['data']['hms'])

    def OnPaint(self):
        print('OnPaint')
        self.dc.Clear()

        timeret = self.pframe.timeOffset()
        print(timeret)
        if timeret['errcode'] == 10000:
            self.StopTimer()
            # self.st2.SetLabel(timeret['errmsg'])
            # font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
            # self.dc.SetFont(font)
            # self.dc.DrawText(timeret['errmsg'], 5, 5)
            self.dc.DrawText(timeret['data'][0], 5, 5)
            self.dc.DrawText(timeret['data'][1], 5, 5 + 25)
            self.dc.DrawText(timeret['data'][2], 5, 5 + 50)
            return
        elif timeret['errcode'] > 0:
            self.StopTimer()
            # self.st1.SetLabel(timeret['errmsg'])
            self.dc.DrawText(timeret['errmsg'], 5, 5)
            return

        self.dc.DrawText(timeret['data']['s'], 5, 5)
        self.dc.DrawText(timeret['data']['ms'], 5, 5 + 25)
        self.dc.DrawText(timeret['data']['hms'], 5, 5 + 50)
        # self.st2.SetLabel(timeret['data']['s'])
        # self.st3.SetLabel(timeret['data']['ms'])
        # self.st4.SetLabel(timeret['data']['hms'])

        # self.dc.DrawBitmap(wx.Bitmap("xbdjs.png"),10,10,True)
        # color = wx.Colour(255,0,0)
        # b = wx.Brush(color)

        # self.dc.SetBrush(b)
        # self.dc.DrawCircle(300,125,50)
        # self.dc.SetBrush(wx.Brush(wx.Colour(255,255,255)))
        # self.dc.DrawCircle(300,125,30)

        # font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
        # self.dc.SetFont(font)
        # self.dc.DrawText("Hello wxPython",200,10)

        # pen = wx.Pen(wx.Colour(0,0,255))
        # self.dc.SetPen(pen)
        # self.dc.DrawLine(200,50,350,50)
        # self.dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH))
        # self.dc.DrawRectangle(380, 15, 90, 60)

    def Screenshot(self, event):

        x1, y1 = (0, 0)
        w, h = self.GetSize()
        x, y = self.GetPosition()
        self.SetPosition((x1, y1))

        screen = wx.ScreenDC()
        # screen = self.dc

        bmp = wx.Bitmap(w, h)
        mem = wx.MemoryDC(bmp)
        mem.Blit(0, 0, w, h, screen, x1, y1)

        del mem

        self.SetPosition((x, y))

        png_path = './ss.png'
        bmp.SaveFile(png_path, wx.BITMAP_TYPE_PNG)

        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(wx.BitmapDataObject(bmp))
            wx.TheClipboard.Close()

        os.remove(png_path)



class SettingFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, pos=wx.DefaultPosition, title='', pframe=None):

        wx.Frame.__init__(self, parent, id, title, pos, size=(90, 80), style=no_resize)

        self.pframe = pframe

        self.SetBackgroundColour(wx.Colour('WHITE'))
        # self.panel = wx.Panel(self)

        self.st2 = wx.StaticText(self, -1, "", pos=(5, 5))
        self.st3 = wx.StaticText(self, -1, "", pos=(5, 5 + 25))
        self.st4 = wx.StaticText(self, -1, "", pos=(5, 5 + 50))


class Frame(wx.Frame):
    def __init__(self, parent=None, id=-1, pos=wx.DefaultPosition, title=APP_NAME):

        no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)

        wx.Frame.__init__(self, parent, id, title, pos, size=(300, 190), style=no_resize)

        self.SetBackgroundColour(wx.Colour('WHITE'))

        self.nxbtime = global_btime

        self.SetIcon(wx.Icon(ResourcePath('xbdjs.ico'), wx.BITMAP_TYPE_ICO))  # 窗口左上角的图标

        self.taskBarIcon = TaskBarIcon(self)

        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_ICONIZE, self.OnIconfiy)

    def OnIconfiy(self, event):
        self.Hide()
        event.Skip()
        # if self.tipFrame.IsIconized():
        #     self.tipFrame.Iconize(False)
        # if not self.tipFrame.IsShown():
        #     self.tipFrame.Show(True)
        # self.tipFrame.Raise()
        # pass


    def OnAbout(self, event):
        wx.MessageBox(APP_NAME + ' ' + APP_VERSION, '关于')

    def OnSetting(self, event):
        self.settingFrame.Show(True)

    def OnClose(self, event):
        if self.taskBarIcon.tipFrame:
            self.taskBarIcon.tipFrame.Destroy()
        self.taskBarIcon.Destroy()
        self.Destroy()

    def genErr(self, errcode, errmsg, data={}):
        return {
            'errcode': errcode,
            'errmsg': errmsg,
            'data': data,
        }

    def afterWork(self):
        all_aw = [
            ['落班啦', '做卵啊做', '翻屋企食饭啊喂'],
        ]
        return all_aw[random.randint(0,len(all_aw) - 1)]

    def timeOffset(self):
        nxbtt = self.nxbtime.strip()
        if len(nxbtt) == 0:
            return self.genErr(10001, "时间格式错误-1")
        nxbtt.replace("：", ":")
        # print(nxbtt)
        try:
            time.strptime(nxbtt, "%H:%M")
            nxbtt = nxbtt + ':00'
        except:
            print(nxbtt)
        try:
            time.strptime(nxbtt, "%H:%M:%S")
        except:
            return self.genErr(10002, "时间格式错误-2")
        # print(nxbtt)

        curr_time = datetime.datetime.now()
        ymd = curr_time.strftime("%Y-%m-%d")
        xbymdhis = ymd + ' ' + nxbtt
        timestamp = int(time.mktime(curr_time.timetuple()))
        time_arr = time.strptime(xbymdhis, "%Y-%m-%d %H:%M:%S")
        xbtimestamp = int(time.mktime(time_arr))

        offsett = xbtimestamp - timestamp
        if offsett < 0:
            return self.genErr(10000, "已下班", self.afterWork())

        ret_s = str(offsett) + "秒"
        m = int(offsett / 60)
        s = int(offsett % 60)
        ret_ms = str(m) + "分" + str(s) + "秒"
        h = int(offsett / 3600)
        remain = offsett % 3600
        m = int(remain / 60)
        s = remain % 60
        ret_hms = str(h) + "时" + str(m) + "分" + str(s) + "秒"
        return self.genErr(0, "", {
            '_hms': (h, m, s),
            's': ret_s,
            'ms': ret_ms,
            'hms': ret_hms,
        })


class Homepage(wx.Panel):
    def __init__(self, parent, pframe = None):
        wx.Panel.__init__(self, parent)

        self.pframe = pframe

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)

        self.st1 = wx.StaticText(self, -1, "距离下班还有:", pos=(5, 5))
        self.st2 = wx.StaticText(self, -1, "", pos=(90, 5))
        self.st3 = wx.StaticText(self, -1, "", pos=(90, 5 + 25))
        self.st4 = wx.StaticText(self, -1, "", pos=(90, 5 + 50))
        self.timer.Start(1000)

    def StopTimer(self):
        self.st2.SetLabel("")
        self.st3.SetLabel("")
        self.st4.SetLabel("")
        self.timer.Stop()
        time.sleep(0.1)

    def OnTimer(self, event):
        timeret = self.pframe.timeOffset()
        if timeret['errcode'] == 10000:
            self.StopTimer()
            self.st2.SetLabel(timeret['data'][0])
            self.st3.SetLabel(timeret['data'][1])
            self.st4.SetLabel(timeret['data'][2])
            return
        elif timeret['errcode'] > 0:
            self.StopTimer()
            self.st1.SetLabel(timeret['errmsg'])
            return

        self.st2.SetLabel(timeret['data']['s'])
        self.st3.SetLabel(timeret['data']['ms'])
        self.st4.SetLabel(timeret['data']['hms'])


class Settingpage(wx.Panel):
    def __init__(self, parent, pframe = None, hframe = None):
        wx.Panel.__init__(self, parent)
        self.pframe = pframe
        self.hframe = hframe

        self.st1 = wx.StaticText(self, -1, "下班时间:", pos=(5, 10))
        self.xbtime = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER, value=global_btime, pos=(70, 5), size=(150, 25))

        # print('Settingpage')
        self.xbtime.Bind(wx.EVT_TEXT, self.timerSet)

        # self.openBtn = wx.Button(self, -1, '确定', size=(75, 25), pos=(5, 90), style=wx.BORDER_NONE)
        # self.openBtn.Bind(wx.EVT_BUTTON, self.timerSet)

        # self.nxbtime = self.xbtime.GetValue()

    def timerSet(self, event):
        # self.st1.SetLabel("距离下班还有:")
        self.nxbtime = self.xbtime.GetValue()
        # print(self.nxbtime)
        global_config.set('base', 'time', self.nxbtime)
        global_config.write(open(config_path, 'w'))
        self.pframe.nxbtime = self.nxbtime
        if not self.hframe.timer.IsRunning():
            self.hframe.timer.Start(1000)

class App(wx.App):
    def OnInit(self):

        name = "xbdjs-%s"%wx.GetUserId()
        self._checker = wx.SingleInstanceChecker(name)
        if self._checker.IsAnotherRunning():
            raise Exception("Another program instance is already running, aborting.")
            return False

        self.frame = Frame()

        self.tabs = wx.Notebook(self.frame)
        self.homepage = Homepage(self.tabs, pframe = self.frame)
        self.tabs.AddPage(self.homepage, '首页')
        self.tabs.AddPage(Settingpage(self.tabs, pframe = self.frame, hframe = self.homepage), '设置')

        self.frame.Centre()
        self.frame.Show(True)
        return True

    def OnExit(self):
        del self._checker
        return 0

if __name__ == '__main__':
    app = App()
    app.MainLoop()